home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 November
/
EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso
/
earcd
/
program
/
misc
/
fpl-v13.lha
/
fpl
/
src
/
caller.c
next >
Wrap
C/C++ Source or Header
|
1995-08-22
|
14KB
|
470 lines
/******************************************************************************
* FREXX PROGRAMMING LANGUAGE *
******************************************************************************
caller.c
For FPL debugging...
Only part of the executable file version of FPL.
*****************************************************************************/
/************************************************************************
* *
* fpl.library - A shared library interpreting script langauge. *
* Copyright (C) 1992-1995 FrexxWare *
* Author: Daniel Stenberg *
* *
* This program is free software; you may redistribute for non *
* commercial purposes only. Commercial programs must have a written *
* permission from the author to use FPL. FPL is *NOT* public domain! *
* Any provided source code is only for reference and for assurance *
* that users should be able to compile FPL on any operating system *
* he/she wants to use it in! *
* *
* You may not change, resource, patch files or in any way reverse *
* engineer anything in the FPL package. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* *
* Daniel Stenberg *
* Ankdammsgatan 36, 4tr *
* S-171 43 Solna *
* Sweden *
* *
* FidoNet 2:201/328 email:dast@sth.frontec.se *
* *
************************************************************************/
#include "FPL.h"
#include "reference.h" /* should be <FPL/reference.h> */
#ifdef AMIGA
#include <exec/types.h>
#include <proto/exec.h>
int CXBRK(void) { return(0); } /* Disable Lattice/SAS CTRL/C handling */
int chkabort(void) { return(0); } /* really */
#ifdef SHARED
#include <exec/libraries.h>
#include <libraries/dos.h>
#include "/include/pragmas/FPL_pragmas.h"
#include "/include/clib/FPL_protos.h"
struct Library *FPLBase = NULL;
#endif
#define REG(x) register __ ## x
#elif defined(UNIX) /* #ifdef AMIGA */
#include <sys/types.h>
#if defined(__GCC_NEW_VARARGS__) /* && defined(__GCC__) */
/*
* If you want this file to be compiled using the va_* macros instead of the
* dirty "address of parameter version", define as below!
* (Without this define, SunOS 4.1.x versions will likely crash!)
*/
#define VARARG_FUNCTIONS /* should be defined before the includes below */
#endif
#define REG(x)
#define TRUE 1
#define FALSE 0
#include "../include/clib/FPL_protos.h"
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#if defined(AMIGA) && defined(SHARED)
#define CALLER __saveds
#define ASM __asm
#else
#define CALLER
#define ASM
#endif
long ASM func(REG(a0) struct fplArgument *);
long ASM inter(REG(a0) void *);
void CALLER ASM MyFree(REG(a1) void *, REG(d0) long);
void CALLER ASM *MyAlloc(REG(d0) long);
long ASM newline(REG(a0) void *);
int memory_counter=0;
int maxmemory_counter=0;
int mallocs=0;
int newlines=0;
enum myfunctions {
FN_GETINT,
FN_GETSTRING,
FN_OUTPUT,
FN_EXECUTE,
FN_PRINTF,
FN_TEST,
FN_OPENL,
FN_CLOSEL,
VR_TEST /* first variable ever! */
};
/**********************************************************************
*
* int main(int, char **)
*
* This function is not included in the run time library version.
*
******/
void *key;
int main(int argc, char **argv)
{
long n, end=0;
long count=0;
int pre_mallocs;
long pre_malloc;
struct fplSymbol *symbols;
long i;
long Version_I,Revision_I;
#if defined(SHARED) && defined(AMIGA)
if(!(FPLBase=OpenLibrary(FPLNAME, 5))) {
printf("Error opening %s!\n", FPLNAME);
return(-1);
}
#endif
if(argc<2) {
printf("Usage: SFPL <FPL program file name>\n");
#if defined(AMIGA) && defined(SHARED)
CloseLibrary((struct Library *)FPLBase);
#endif
return 0;
}
key=fplInitTags(func,
FPLTAG_INTERVAL, (unsigned long)inter, /* interval func */
FPLTAG_USERDATA, (unsigned long)&count, /* user data */
FPLTAG_INTERNAL_DEALLOC, (unsigned long)MyFree,
FPLTAG_INTERNAL_ALLOC, (unsigned long)MyAlloc,
FPLTAG_MINSTACK, 7000,
FPLTAG_CACHEALLFILES, FPLCACHE_EXPORTS,
FPLTAG_REREAD_CHANGES, TRUE,
FPLTAG_IDENTITY, argv[0], /* identify us! */
FPLTAG_DEBUG, TRUE, /* run in debug mode! */
FPLTAG_DONE);
fplSendTags( key, FPLSEND_GETVERSION, &Version_I,
FPLSEND_GETREVISION, &Revision_I, FPLSEND_DONE);
printf("Using FPL version %d.%d.\n",Version_I,Revision_I);
fplAddFunction(key, "getint", FN_GETINT, 'I', "s", NULL);
fplAddFunction(key, "getstring", FN_GETSTRING, 'S', "s", NULL);
fplAddFunction(key, "output", FN_OUTPUT, 'S', "O", NULL);
fplAddFunction(key, "runfile", FN_EXECUTE, 'I', "S", NULL);
fplAddFunction(key, "printf", FN_PRINTF, 'I', "So>", NULL);
fplAddFunction(key, "array", FN_TEST, 'I', "R", NULL);
fplAddVariable(key, "_TEST_", VR_TEST, 'S', NULL, NULL);
pre_mallocs=mallocs;
pre_malloc=memory_counter;
#if 1
if(!end && argc>1) {
int i;
for(i=1; i<argc; i++) {
char *string=NULL;
end=fplExecuteFileTags(key, argv[i],
FPLTAG_ISOLATE, TRUE,
FPLTAG_STRING_RETURN, &string,
FPLTAG_DONE);
if(string) {
printf("The '%s' program returned '%s'\n", argv[i], string);
fplFreeString(key, string);
}
}
}
#else
{
char *program1 =
"string lastsearch;\n export void tut(void) {string test; test = lastsearch;} }";
fplExecuteScriptTags(key, &program1, 1,
FPLTAG_KIDNAP_CACHED, TRUE,
FPLTAG_CACHEFILE, FPLCACHE_EXPORTS,
FPLTAG_PROGNAME, "program1",
FPLTAG_DONE);
program1 = "tut(); ";
fplExecuteScriptTags(key, &program1, 1,
FPLTAG_DONE);
}
#endif
#if 0
fplSendTags(key, FPLSEND_GETSYMBOL_FUNCTIONS, &symbols, FPLSEND_DONE);
printf("\n---------------------\nAll exported functions:\n");
for(i=0; i<symbols->num; i++)
printf("%s ", symbols->array[i]);
fplSendTags(key, FPLSEND_GETSYMBOL_FREE, symbols, FPLSEND_DONE);
fplSendTags(key, FPLSEND_GETSYMBOL_VARIABLES, &symbols, FPLSEND_DONE);
printf("\n---------------------\nAll exported variables:\n");
for(i=0; i<symbols->num; i++)
printf("%s ", symbols->array[i]);
fplSendTags(key, FPLSEND_GETSYMBOL_FREE, symbols, FPLSEND_DONE);
fplSendTags(key, FPLSEND_GETSYMBOL_CACHEDFILES, &symbols, FPLSEND_DONE);
printf("\n---------------------\nAll cached files:\n");
for(i=0; i<symbols->num; i++)
printf("%s ", symbols->array[i]);
fplSendTags(key, FPLSEND_GETSYMBOL_FREE, symbols, FPLSEND_DONE);
#endif
fplSendTags(key,
FPLSEND_GETRETURNCODE, &n,
FPLSEND_FLUSHFILE, 0,
FPLSEND_FLUSHCACHE, 1,
FPLSEND_DONE);
fplFree(key); /* free all shit FPL uses internally */
#if defined(AMIGA) && defined(SHARED)
CloseLibrary((struct Library *)FPLBase);
#endif
#ifdef DEBUG_INFO
printf("\n-----------------------------------------\n");
printf("Return code : %d\n", n);
printf("Interval func : %d\n", count);
printf("Newlines : %d\n", newlines);
printf("Pre mallocs : %d\n", pre_mallocs);
printf("Pre memory use: %d\n", pre_malloc);
printf("Malloc : %d\n", mallocs-pre_mallocs);
printf("memory use : %d\n", maxmemory_counter-pre_malloc);
printf("-----------------------------------------\n");
#endif
if(memory_counter)
printf(">ALARM!!< Not freed mem : %d bytes!\n", memory_counter);
return end;
}
#define TEST_STRING "I_returned_this_from_the_interface_function!"
long ASM func(REG(a0) struct fplArgument *arg)
{
int ret;
long col;
char *name;
char *string;
void *anchor=arg->key;
char systemline[80];
switch(arg->ID) {
case VR_TEST:
fplSendTags(anchor, FPLSEND_STRING, "internal variable!", FPLSEND_DONE);
break;
case FN_TEST:
{
long new[2]={0,-1};
long *integer;
fplReferenceTags(anchor, arg->argv[0],
FPLREF_NAME, &name,
FPLREF_TYPE, &col,
FPLREF_GET_STRING, &string,
FPLREF_GET_INTEGER, &integer,
FPLREF_DONE);
printf("Received a reference to the %s %svariable called '%s'\n",
col&FPLREF_TYPE_STRING?"string":"integer",
col&FPLREF_TYPE_ARRAY?"array ":"",
name);
if(col&FPLREF_TYPE_ARRAY) {
struct fplRef ref;
fplReferenceTags(anchor, arg->argv[0],
FPLREF_ARRAY_INFO, &ref,
FPLREF_DONE);
if(1 == ref.Dimensions) {
long dims[]={0, -1};
for(col=0; col<ref.ArraySize[0]; col++) {
dims[0]=col;
fplReferenceTags(anchor, arg->argv[0],
FPLREF_ARRAY_ITEM, &dims[0],
FPLREF_GET_STRING, &name,
FPLREF_DONE);
if(name[0])
printf("#%d: %s\n", col, name);
}
new[0] = 5;
fplReferenceTags(anchor, arg->argv[0],
FPLREF_ARRAY_ITEM, &dims[0],
FPLREF_SET_MY_STRING, "externally set",
FPLREF_DONE);
ref.ArraySize = new;
new[0] = 20;
fplReferenceTags(anchor, arg->argv[0],
FPLREF_ARRAY_RESIZE, &ref,
FPLREF_DONE);
}
}
else if(col&FPLREF_TYPE_STRING) {
printf("It holds the string '%s'\n", string);
if(string=(char *)fplAllocString(anchor, strlen(TEST_STRING))) {
strcpy(string, TEST_STRING);
fplReferenceTags(anchor, arg->argv[0],
FPLREF_SET_STRING, string,
FPLREF_END);
fplReferenceTags(anchor, arg->argv[0],
FPLREF_SET_MY_STRING, TEST_STRING,
FPLREF_END);
}
} else if(col&FPLREF_TYPE_INTEGER) {
printf("It holds the number %d\n", *integer);
}
}
break;
case FN_PRINTF:
#if defined(AMIGA)
vprintf(arg->argv[0], (char *)&arg->argv[1]);
#elif defined(UNIX)
vfprintf(stderr, arg->argv[0], (char *)&arg->argv[1]);
#endif
break;
case FN_OUTPUT: /* output */
if(arg->format[0]==FPL_STRARG) /* we got a string! */
string="%s";
else
string="%d";
#if defined(AMIGA)
printf(string, arg->argv[0]);
#elif defined(UNIX)
fprintf(stderr, string, arg->argv[0]);
#endif
/*
if(arg->format[0]==FPL_STRARG)
fplSendTags(anchor, FPLSEND_INT, 1, FPLSEND_DONE);
else
fplSendTags(arg->key,
FPLSEND_STRING, "returned",
FPLSEND_DONE);
*/
break;
case FN_GETSTRING:
if(string=(char *)fplAlloc(anchor, 64)) {
if(arg->argc)
printf("%s", arg->argv[0]);
fgets(string, 64, stdin);
ret=fplSendTags(arg->key,
FPLSEND_STRING, string,
FPLSEND_STRLEN, strlen(string)-1,
FPLSEND_DONE);
fplDealloc(anchor, string);
} else
ret=FPLERR_OUT_OF_MEMORY;
return(ret);
case FN_EXECUTE:
ret=fplExecuteFile(anchor, arg->argv[0], NULL);
return(ret);
break;
case FPL_GENERAL_ERROR:
{
char buffer[FPL_ERRORMSG_LENGTH];
fplSendTags(anchor,
FPLSEND_GETVIRLINE, &col,
FPLSEND_GETVIRFILE, &name,
FPLSEND_DONE);
if(*name=='\"') {
ret=0;
name++;
while(name[ret] && name[ret]!='\"')
ret++;
string=(char *)fplAlloca(anchor, ret+1);
memcpy(string, name, ret);
string[ret]='\0';
} else {
string=name;
ret=0;
}
printf("\n>>> %s\n",
fplGetErrorMsg(arg->key, (long)arg->argv[0], buffer));
printf(">>> Line %d in file \"%s\". <<<\n", col, string);
if(ret)
fplDealloca(anchor, string);
}
break;
case FPL_UNKNOWN_FUNCTION:
col=22; /* only to breakpoint */
break;
case FN_GETINT:
if(arg->argc)
printf("%s", (char *)arg->argv[0]);
scanf("%d", &ret);
ret=fplSendTags(anchor, FPLSEND_INT, ret, FPLSEND_DONE);
return(ret);
}
return FPL_OK;
}
long ASM inter(REG(a0) void *count)
{
static line=-1;
#if 0
static char *name;
long current_line;
char *curr_name;
fplSendTags(key, FPLSEND_GETVIRLINE, ¤t_line, FPLSEND_DONE);
fplSendTags(key, FPLSEND_GETVIRFILE, &curr_name, FPLSEND_DONE);
if(line!=current_line || name != curr_name) {
line=current_line;
name=curr_name;
/* fprintf(stderr, " < %d %s > ", line, name?name:"unknwon"); */
}
#endif
(*(int *)count)++; /* just to count the number of times this routine has been
called. */
return(0);
}
void CALLER ASM MyFree(REG(a1) void *pntr, REG(d0) long size)
{
memory_counter-=size;
memset(pntr, 0xaa, size); /* mess up this area before free! */
free(pntr);
}
void CALLER ASM *MyAlloc(REG(d0) long size)
{
void *mem;
mallocs++;
if((memory_counter+=size)>maxmemory_counter)
maxmemory_counter=memory_counter;
mem=malloc(size);
if(mem)
memset(mem, 0xaa, size); /* mess up this area before free! */
return (mem);
}